import { createSlice } from "@reduxjs/toolkit";
import {
  reqGetAllTodos, 
  reqCreateNewTodo,
  reqUpdateTodo,
  reqRemoveTodo
} from '../../api/todos'

//创建 slice 对象
let todoSlice = createSlice({
  //别名
  name: "todo",
  //初始化值
  initialState: [],
  //reducers 属性
  reducers: {
    //新增任务  addTodo({id: 3, title: '吃泡馍', done: false})
    addTodo: (state, { payload }) => {
      //压入数组
      state.push(payload);
    },
    //切换任务的函数 checkTodo({id: 2, done: true})
    checkTodo: (state, { payload }) => {
      //遍历 state
      state.forEach((item) => {
        //判断
        if (item.id === payload.id) {
          //更新状态
          item.done = payload.done;
        }
      });
    },
    //删除功能  removeTodo(2);
    removeTodo: (state, { payload }) => {
      //删除数组中指定 id 的元素
      state.forEach((item, index) => {
        //判断当前任务的 id 是否为要删除的 id
        if (item.id === payload) {
          //删除这个元素
          state.splice(index, 1);
        }
      });
    },
    //修改所有任务的状态 checkAllTodo(true);
    checkAllTodo: (state, { payload }) => {
      //遍历
      state.forEach((item) => {
        item.done = payload;
      });
    },
    //清除已经完成的任务  removeDoneTodos()
    removeDoneTodos: (state, {payload}) => {
      let index = 0;
      while(index < state.length){
        if(state[index].done){
          state.splice(index, 1);
        }else{
          index += 1
        }
      }
    },
    //设置 todos 的功能  setTodos([{id:1, title: x, done: true}, {id: 2, title: x, done: false}])
    setTodos: (state, {payload}) => {
      //设置保存的状态  state 本质是一个代理对象. 
      // state = payload // 不能直接赋值    defineProperty
      state.push(...payload);// ... 扩展运算符  
    }
  },
});

//获得 action 函数.  
// addTodo  checkTodo 返回值都是 action 对象
export let { 
  addTodo, 
  checkTodo, 
  removeTodo, 
  checkAllTodo,
  removeDoneTodos,
  setTodos
} = todoSlice.actions;

//定义一个异步的 action 函数
export let asyncReqGetTodos = () => {
  return async (dispatch) => {
    //异步任务  [{}, {}]
    let data = await reqGetAllTodos();// 
    //同步修改内部状态 todos
    dispatch(setTodos(data));
  }
}

//封装函数 发送请求 新增任务   dispatch(asyncReqAddTodo({title: 'xx', done: false}))
export let asyncReqAddTodo = (payload) => {
  return async dispatch => {
    //发送请求新增任务
    let data = await reqCreateNewTodo(payload);
    //新增redux中的任务
    // console.log(addTodo(data));
    dispatch(addTodo(data));
  }
}

//封装函数发送请求 更新任务的状态  dispatch(asyncReqCheckTodo({id: 2, done: true}))
export let asyncReqCheckTodo = (payload) => { // payload  {id: 2, done: true}
  return async  dispatch => {
    //发送请求 更新状态
    await reqUpdateTodo(payload.id, payload.done);
    //修改 redux 中指定任务的状态
    dispatch(checkTodo(payload))
  }
}

//封装函数 dispatch(asyncReqRemoveTodo(2));
export let asyncReqRemoveTodo = (id) => {
  return async dispatch => {
    //发送请求
    await reqRemoveTodo(id);
    //更新 redux 状态
    dispatch(removeTodo(id));
  }
}



//暴露 slice 对象
export default todoSlice.reducer;
